/**
 * Copyright 2012 BTChip 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.btchip;

import com.btchip.protocol.BTChip;
import com.btchip.protocol.BTChipCommunicationException;
import com.btchip.protocol.BTChipInvalidStatusWordException;

public class BTChipAPI {
	
	private static byte SELECT_CURVE[] = { (byte)0x80, (byte)0xa4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xb1, (byte)0xc0 };
	
	public static byte[] exchangeOK(BTChip chip, byte[] apdu) throws BTChipInvalidStatusWordException, BTChipCommunicationException {
		byte response[] = chip.exchange(apdu);
		int sw = ((response[response.length - 2] & 0xff) << 8) + (response[response.length - 1] & 0xff);
		if ((response[response.length - 2] != (byte)0x90) && (response[response.length - 1] != 0x00)) {
			throw new BTChipInvalidStatusWordException(sw);
		}
		return response;
	}
	
	public static void init(BTChip chip) throws BTChipInvalidStatusWordException, BTChipCommunicationException {
		exchangeOK(chip, SELECT_CURVE);
	}
	
	public static BTChipKeypair generateKeypair(BTChip chip, int privateKeyEncryptionVersion) throws BTChipInvalidStatusWordException, BTChipCommunicationException {
		byte[] apdu = new byte[7];
		apdu[0] = (byte)0xe0;
		apdu[1] = (byte)0x20;
		apdu[2] = (byte)0x00;
		apdu[3] = (byte)0x00;
		apdu[4] = (byte)0x02;
		apdu[5] = (byte)privateKeyEncryptionVersion;
		apdu[6] = (byte)0x00;
		byte[] response = exchangeOK(chip, apdu);
		byte[] publicKey = new byte[response[0]];
		byte[] privateKey = new byte[response[1 + response[0]]];
		System.arraycopy(response, 1, publicKey, 0, publicKey.length);
		System.arraycopy(response, 1 + publicKey.length + 1, privateKey, 0, privateKey.length);
		return new BTChipKeypair(publicKey, privateKey);
	}
	
	public static byte[] sign(BTChip chip, int privateKeyEncryptionVersion, byte[] key, byte[] hash) throws BTChipInvalidStatusWordException, BTChipCommunicationException {
		byte[] apdu = new byte[5 + 1 + 1 + key.length + hash.length];
		apdu[0] = (byte)0xe0;
		apdu[1] = (byte)0x40;
		apdu[2] = (byte)0x00;
		apdu[3] = (byte)0x00;
		apdu[4] = (byte)(1 + 1 + key.length + hash.length);
		apdu[5] = (byte)privateKeyEncryptionVersion;
		apdu[6] = (byte)key.length;
		System.arraycopy(key, 0, apdu, 7, key.length);
		System.arraycopy(hash, 0, apdu, 7 + key.length, hash.length);
		return exchangeOK(chip, apdu);
	}

}
